/**
 * @file STL_RtspEnableTest.h
 * @author Derek Liu (yjkhtddx@sina.com)
 * @brief 
 * @version 0.1
 * @date 2021-02-08
 * 
 * @copyright Copyright Sci-Tech Laboratories (c) 2021
 * 
 */

#ifndef __STL_RTSP_ENABLE_TEST_H__
#define __STL_RTSP_ENABLE_TEST_H__

#include <string>
#include <stdint.h>
#include <functional>
#include <thread>
#include <mutex>
#include <list>
#include <queue>
#include <memory>
#include <map>
#include "STL_Tools.h"
#include "STL_RtspResParser.h"

namespace STL
{
    class STL_RtspEnableTest
    {
    public:
        typedef enum TestStatus_e
        {
            TestStatus_None,              // 待检测
            TestStatus_Initing,           // 初始化中
            TestStatus_Connecting,        // 连接中
            TestStatus_Testing,           // 测试中
            TestStatus_InitError,         // 初始化错误(会产生上报的状态)
            TestStatus_ConnectError,      // 连接错误(会产生上报的状态)
            TestStatus_TestError,         // 测试错误(会产生上报的状态)
            TestStatus_AuthorzationError, // 认证错误(会产生上报的状态)
            TestStatus_Successed          // 成功(会产生上报的状态)
        } TestStatus;

        typedef struct TestInfo_t
        {
            int socket = -1;
            TestStatus status = TestStatus_None;
            STL_RtspResParser parser;
            bool isSendAuth = false;
            bool isDone = false;
            int cseq = 1;
            std::string rtspUrl = "";
            std::string url = "";
            std::string ip = "";
            uint16_t port = 0;
            std::string username = "";
            std::string password = "";
            std::mutex mutex;
            std::string sdp = "";
            long timestamp;
            TestInfo_t(std::string rtspUrl)
            {
                this->rtspUrl = rtspUrl;
            }
        } TestInfo;
        typedef std::function<void(std::string /*rtspUrl*/, STL_RtspEnableTest::TestStatus /*status*/, std::string /*sdp*/)> ResultCallback;

    private:
        STL_RtspEnableTest();
        ~STL_RtspEnableTest();

    public:
        static STL_RtspEnableTest *getInstance()
        {
            static STL_RtspEnableTest instance;
            return &instance;
        };

    public:
        /**
         * @brief 添加测试URL
         * 
         * @return int 
         */
        int addTestRtspUrl(std::string rtspUrl);
        std::string getRtspUrlFromSocket(int socket);
        void startCheckRtspUrl(std::string rtspUrl);
        void setStatus(std::string rtspUrl, STL_RtspEnableTest::TestStatus status);
        void setCheckUsleepTime(useconds_t time)
        {
            m_usleepTime = time;
        };

    private:
        void reportStatus(std::string rtspUrl, STL_RtspEnableTest::TestStatus status, std::string sdp = "");

    public:
        STL_SYNTHESIZE(STL::STL_RtspEnableTest::ResultCallback, m_ResultCallback, ResultCallback);

    private:
        bool m_run;
        useconds_t m_usleepTime;
        std::thread m_thread;
        std::mutex m_mutex;
        void checkThread();

    private:
        std::mutex m_testMapMutex;
        std::map<std::string /*rtspUrl*/, TestInfo * /*testInfo*/> m_testMap;
    };
} // namespace STL

#endif //__STL_RTSP_ENABLE_TEST_H__